#ifndef QQTFINDSERVERMANAGER_H
#define QQTFINDSERVERMANAGER_H

#include <QObject>

#include <qqtudpclient.h>
#include <qqtudpserver.h>

#include <qqtprotocol.h>
#include <qqtdataprotocol.h>
#include <qqtprotocolmanager.h>

#include <qqtframe.h>

#include <qqthighgrade_global.h>

class QQtBeServerProtocol;
class QQtBeServerProtocolManager;
class QQtFindServerProtocol;

/**
 * @brief The QQtBeServerManager class
 * BeServer
 * 服务器。
 * 需要先启动。
 */
class QQTHIGHGRADESHARED_EXPORT QQtBeServerManager : public QObject
{
    Q_OBJECT

public:
    explicit QQtBeServerManager ( QObject* parent = 0 );
    virtual ~QQtBeServerManager();

    //设置BeServer监听地址、端口。
    void setListeningAddress ( QHostAddress address, int port = 4408 );

    void setListeningPort ( int port = 4408 );

    //如果此处设置改变>1次，需要重启Be服务器端。
    void setTellClient ( QString ip, int port );

    QString tellClientIP();
    int tellClientPort();

protected:

private:
    QQtBeServerProtocolManager* m0;
    QQtUdpServer* s0;

    QString mIP;
    int mPort;
};

/**
 * @brief The QQtFindServerManager class
 * FindServer
 * 客户端。
 */
class QQTHIGHGRADESHARED_EXPORT QQtFindServerManager : public QObject
{
    Q_OBJECT

public:
    explicit QQtFindServerManager ( QObject* parent = 0 );
    virtual ~QQtFindServerManager();

    //设置BeServer的监听端口
    void setServerPort ( int port = 4408 );
    //设置FindServer，也就是本地的发送、接收数据的端口。
    void setLocalAddress ( QHostAddress address, int port );

    void setLocalPort ( int port );

    void sendFindServer();

signals:
    void signalFindServer ( QString ip, int port );

protected:

private:
    QQtUdpClient* c0;
    QQtFindServerProtocol* p0;
};

/**
 * @brief The QQtBeServerProtocolManager class
 */
class QQTHIGHGRADESHARED_EXPORT QQtBeServerProtocolManager : public QQtProtocolManager
{
    Q_OBJECT
public:
    explicit QQtBeServerProtocolManager ( QObject* parent = 0 );
    virtual ~QQtBeServerProtocolManager();

    void setLocalIpPort ( QString ip, int port );

private:
    QString mIP;
    int mPort;

    // QQtProtocolManager interface
public:
    virtual QQtProtocol* createProtocol() override;
};

/**
 * @brief The QQtBeServerProtocol class
 * 1. 支持客户端查找服务器
 * 2. 支持服务器主动发布自己的IP、端口
 * server
 *
 * cmd_type
 * [0] "find_server", "server_ack"
 *
 * [0] "find_server"
 * [1] ...
 *
 * [0] "server_ack"
 * [1]
 *     ["ip"]
 *     ["port"]
 */
class QQTHIGHGRADESHARED_EXPORT QQtBeServerProtocol : public QQtDataProtocol
{
    Q_OBJECT

public:
    explicit QQtBeServerProtocol ( QObject* parent = 0 );
    virtual ~QQtBeServerProtocol();

    void setLocalIpPort ( QString ip, int port );

    void sendBeServerMessage();

protected:

private:

signals:

    // QQtDataProtocol interface
public:
    virtual void recvMessage ( const QQtDataSerialization& data ) override;

private:
    QString mIP;
    int mPort;
};

/**
 * @brief The QQtFindServerProtocol class
 * 1. 支持客户端查找服务器
 * 2. 支持服务器主动发布自己的IP、端口
 * client
 *
 * cmd_type
 * [0] "find_server", "server_ack"
 *
 * [0] "find_server"
 * [1] ...
 *
 * [0] "server_ack"
 * [1]
 *     ["ip"]
 *     ["port"]
 */
class QQTHIGHGRADESHARED_EXPORT QQtFindServerProtocol : public QQtDataProtocol
{
    Q_OBJECT

public:
    explicit QQtFindServerProtocol ( QObject* parent = 0 );
    virtual ~QQtFindServerProtocol();

    void sendFindServerRequest();
protected:

private:

signals:
    void signalFindServer ( QString ip, int port );

    // QQtDataProtocol interface
public:
    virtual void recvMessage ( const QQtDataSerialization& data ) override;

private:
    QString mIP;
    int mPort;
};

#endif // QQTFINDSERVERMANAGER_H

